home *** CD-ROM | disk | FTP | other *** search
- -> FILE: ESrc:Own/bppcfixfix.e REV: 1 --- patch p5/dce library to be loadable from disk
- /* History
- 0 Started in September 2000.
- */
-
- OPT PREPROCESS
-
- #define VERSION 'bppcfixfix 1.0.0 (1.9.2000)'
-
- MODULE 'dos/dos','dos/doshunks','exec/memory','exec/execbase',
- 'graphics/gfxbase','exec/resident','exec/nodes'
-
- ENUM ARG_FROM,ARG_TO,NUMARGS
-
- ENUM ER_OK,ER_PARAM,ER_MEM,ER_INPUTFILE,ER_OUTPUTFILE,ER_READ,
- ER_WRITE,ER_PATCH
-
- DEF array[NUMARGS]:ARRAY OF LONG
-
- PROC main() HANDLE
- DEF rdargs = NIL, name:PTR TO CHAR, ioerr, ret
- DEF r, pname[64]:STRING
- DEF ifh = NIL, ofh = NIL, ofile
- DEF filelen, buf
-
- IF (KickVersion(37) = 0)
- WriteF('This program requires AmigaOS 2.04+\n');
- RETURN RETURN_FAIL
- ENDIF
-
- FOR r := 0 TO NUMARGS - 1; array[r] := 0; ENDFOR
- IF ((rdargs := ReadArgs('FROM/A,TO/A',
- array, NIL)) = NIL) THEN Raise(ER_PARAM)
-
- -> open input file
- IF ((ifh := Open(array[ARG_FROM], MODE_OLDFILE)) = NIL) THEN Raise(ER_INPUTFILE)
- -> open output file
- ofile := array[ARG_TO]
- IF ((ofh := Open(ofile, MODE_NEWFILE)) = NIL) THEN Raise(ER_OUTPUTFILE)
-
- buf := NewR(filelen := FileLength(array[ARG_FROM]))
- IF (Read(ifh, buf, filelen) <> filelen) THEN Raise(ER_READ)
- IF (patch(buf, filelen) = FALSE) THEN Raise(ER_PATCH)
- IF (Write(ofh, buf, filelen) <> filelen) THEN Raise(ER_WRITE)
-
- EXCEPT DO
- IF (exception)
- IF ((exception = "NEW") OR (exception = "MEM")) THEN exception := ER_MEM
-
- IF (ioerr := IoErr())
- PrintFault(ioerr, NIL)
- ENDIF
- GetProgramName(pname, StrMax(pname) - 1)
- PrintF('\s: \s\n', pname,
- ListItem(['', 'argument error', 'no memory',
- 'could not open input file',
- 'could not open output file',
- 'could not read file',
- 'could not write file',
- 'could not patch file'
- ], exception))
- ret := RETURN_ERROR
- ELSE
- ret := RETURN_OK
- ENDIF
-
- IF (ofh)
- Close(ofh)
- IF (exception) THEN DeleteFile(ofile)
- ENDIF
- IF (ifh) THEN Close(ifh)
- IF (rdargs) THEN FreeArgs(rdargs)
- ENDPROC ret
-
- CHAR '$VER: ',VERSION,0
-
-
- PROC patch(buf:PTR TO LONG, len)
- DEF ret = FALSE
- DEF hunk0offs, hunk0len
- DEF r, tag:PTR TO rt, start:PTR TO LONG
- DEF init = 0, i, x
-
- IF ((len < 40960) OR ((len AND 3) <> 0)) THEN RETURN FALSE
-
- -> check header
- IF ((buf[] <> HUNK_HEADER) OR (buf[1] <> 0)) THEN RETURN FALSE
- IF ((r := buf[2]) = 0) THEN RETURN FALSE
- IF ((buf[4] - buf[3] + 1) <> r) THEN RETURN FALSE
-
- start := buf + 20
- REPEAT
- IF ((start[] AND $E0000000) = $C0000000)
- ADDQ.L #8,start
- ELSE
- ADDQ.L #4,start
- ENDIF
- r--
- UNTIL r = 0
-
- r := start[] AND $1FFFFFFF
- IF ((r <> HUNK_CODE) AND (r <> HUNK_DATA)) THEN RETURN FALSE
- hunk0len := start[1] * 4
- hunk0offs := start + 8 - buf
-
- ->PrintF('hunk0offs: $\h[08] hunk0len: $\h[08]\n', hunk0offs, hunk0len)
-
- -> find ROMTag
-
- FOR r := 0 TO hunk0len STEP 2
- EXIT ret
- tag := buf + hunk0offs + r
-
- IF ((tag.matchword = RTC_MATCHWORD) AND
- (tag.matchtag = r) AND
- ((tag.endskip AND $FFF00000) = 0) AND
- ((tag.flags AND Not(RTF_COLDSTART OR RTF_AFTERDOS OR RTF_AUTOINIT)) = 0) AND
- (tag.type = NT_LIBRARY) AND
- ((tag.name AND $FFF00000) = 0) AND
- ((tag.idstring AND $FFF00000) = 0))
-
- ->PrintF('romtag at offset $\h\n', hunk0offs + r)
-
- -> find initcode
- IF (tag.init)
- init := hunk0offs + tag.init
- IF (tag.flags AND RTF_AUTOINIT)
- init := hunk0offs + Long(buf + init + 12)
- ENDIF
- ENDIF
-
- IF ((init > hunk0offs) AND (init < (hunk0offs + hunk0len - 2)))
-
- ->PrintF('initcode: $\h[08]\n', init)
-
- -> scan the init code for 'move.l a0,dn'
- FOR i := 0 TO 32 STEP 2
- x := Int(buf + init + i)
- EXIT ((ret <> 0) OR (x = $4E75))
- IF ((x AND $F1FF) = $2008)
- -> patch it! (moveq #0,dn)
- PutInt(buf + init + i, (x AND $0E00) OR $7000)
- ret := 1
- ENDIF
- ENDFOR
- ENDIF
- ENDIF
- ENDFOR
- ENDPROC ret
-